home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 58189 / 58189.xpi / modules / HttpUtils.jsm < prev    next >
Text File  |  2010-01-08  |  10KB  |  293 lines

  1. /*
  2.  * This module provides operations for HTTP items, such as splitting URIs, ...
  3.  */
  4.  
  5. var EXPORTED_SYMBOLS = [ ];
  6. Components.utils.import("resource://csfiremodules/CsFireCommon.jsm");
  7.  
  8. CsFire.HttpUtils = new function() {
  9.     this.CROSSDOMAIN_RELAXED = 0;
  10.     this.CROSSDOMAIN_STRICT = 1;
  11. };
  12.  
  13. /*
  14.  * Determines whether a request is internal (within the browser) or is an
  15.  * internet request.
  16.  *
  17.  * This function is mostly taken from the "RequestPolicy" extension
  18.  */
  19. CsFire.HttpUtils.isRequestInternal = function(uri) {
  20.     var result = false;
  21.     if(uri != null) {
  22.         var scheme = uri.scheme;
  23.         if( scheme == "about" || scheme == "chrome"
  24.                                 || scheme == "data"
  25.                               || scheme == "file"
  26.                               || scheme == "javascript"
  27.                                || scheme == "moz-icon"
  28.                                || scheme == "resource"
  29.                                || scheme == "view-source"
  30.                                || scheme == "wyciwyg" ) {
  31.              result = true;  
  32.          }
  33.     }
  34.     else {
  35.         result = true;
  36.     }
  37.     
  38.     return result;
  39. };
  40.  
  41. /*
  42.  * Splits a URI in its different parts. This function provides more info than
  43.  * the nsIUri interface.
  44.  */
  45. CsFire.HttpUtils.splitUri = function(uri) {
  46.     if(this.isRequestInternal(uri)) {
  47.         // Internal requests often have no host or auth info, which causes errors
  48.         return {"fullUri":    null,
  49.                 "scheme":     uri.scheme,
  50.                 "auth":        null,
  51.                 "host":        null,
  52.                 "port":        null,
  53.                 "path":        null,
  54.                 "item":        null,
  55.                 "params":   null};
  56.     }
  57.     else {
  58.         //extract GET parameters from URI
  59.         var path = uri.path;
  60.         var params = null;
  61.         var splittedParams = null;
  62.         var startParams = uri.path.indexOf('?');
  63.         if(startParams == -1 ) {
  64.             // No parameters available, so set the start index to the end of the path
  65.             startParams = uri.path.length;
  66.         }
  67.         else {
  68.             // Params are available, so extract them from the path and reduce the path
  69.             params = uri.path.substring(startParams, uri.path.length);
  70.             path = path.substr(0, startParams);
  71.             
  72.             // Split the GET parameters and extract the keynames
  73.             splittedParams = this.splitGetParameters(params);
  74.         }
  75.  
  76.         //extract the actual item that's being requested (the 'img.png' of 'http://www.google.be/images/img.png')
  77.         var item = null;
  78.         var startItem = path.lastIndexOf('/');
  79.         if(startItem > 0) {
  80.             item = path.substring(startItem + 1, path.length);
  81.         }
  82.         else if(path.length > 0) {
  83.             item = path.substr(1, path.length);
  84.         }
  85.  
  86.         return {"fullUri":    uri.prePath + uri.path,
  87.                 "scheme":     uri.scheme,
  88.                 "auth":        uri.userPass,
  89.                 "host":        uri.host,
  90.                 "port":        uri.port,
  91.                 "path":        path,
  92.                 "item":        item,
  93.                 "params":   splittedParams};
  94.     }
  95. };
  96.  
  97. /*
  98.  * This function retrieves the part of the path for which Basic authentication
  99.  * is valid.
  100.  */
  101. CsFire.HttpUtils.getAuthenticatedPath = function(uri) {
  102.     var splittedUri = this.splitUri(uri);
  103.     var path = splittedUri.path.substring(0, splittedUri.path.length - splittedUri.item.length);
  104.     return uri.prePath + path;;
  105. }
  106.  
  107. /*
  108.  * This function splits the string of GET parameters and returns a string
  109.  * containing all the keynames.
  110.  */
  111. CsFire.HttpUtils.splitGetParameters = function(stringParams) {
  112.     var paramList = [];
  113.     var params = stringParams.split("?")[1].split("&");
  114.     for(var i = 0; i < params.length; i++) {
  115.         paramList.push(params[i].split("=")[0]);
  116.     }
  117.     return paramList;
  118. };
  119.  
  120. /*
  121.  * This function extracts the cookie header from the HTTP channel. Using this 
  122.  * header, each cookie name is extracted. For this cookie, the properties (expiry
  123.  * date, path, security) are fetched from the cookie database. The function returns
  124.  * a string containing all this info for all cookies of the channel.
  125.  */
  126. CsFire.HttpUtils.extractCookies = function(httpChannel) {
  127.     var uri = httpChannel.URI;
  128.     
  129.     try {
  130.         var cookieJar = [];
  131.         var cookieCount = 0; //count separately, since cookieJar.length seems to be incorrect
  132.         var cookieHeader = httpChannel.getRequestHeader("cookie");
  133.         var cookies = cookieHeader.split(";");
  134.  
  135.         for(var i = 0; i < cookies.length; i++) {
  136.             var cookieName = cookies[i].split("=")[0].replace(/^\s*|\s*$/g,''); //strip whitespace from cookienames
  137.             cookieJar[cookieName] = 1;
  138.             cookieCount++;
  139.         }
  140.  
  141.         // Extract more info about cookies, such as path, expiry date and security
  142.         var cookieInfo = [];
  143.  
  144.         var cookieMgr = Components.classes["@mozilla.org/cookiemanager;1"].getService(Components.interfaces.nsICookieManager2);
  145.         var count = cookieMgr.countCookiesFromHost(uri.host);
  146.         
  147.         var processedCookies = 0;
  148.         for (var e = cookieMgr.enumerator; e.hasMoreElements() && processedCookies < cookieCount;) {
  149.              var cookie = e.getNext().QueryInterface(Components.interfaces.nsICookie);
  150.              if(uri.host.indexOf(cookie.host) != -1 && cookieJar[cookie.name] != null && cookieJar[cookie.name] == 1) {
  151.                  processedCookies++;
  152.                  cookieInfo.push(new Array(cookie.name, cookie.path, cookie.isSecure, cookie.expires));
  153.               }
  154.         }
  155.  
  156.         return cookieInfo;
  157.     }
  158.     catch(e) { 
  159.         return []; 
  160.     }
  161. };
  162.  
  163. /*
  164.  * This function extracts the domain name and tld from an URI
  165.  */
  166. CsFire.HttpUtils.getDomainName = function(stringUri) {
  167.     var startDomain = stringUri.lastIndexOf(".", stringUri.lastIndexOf(".") - 1);
  168.     return stringUri.substring(startDomain + 1, stringUri.length);
  169. }
  170.  
  171. /*
  172.  * Checks if the request has any referrer info or not. If any kind of info is
  173.  * available, true is returned, false otherwise.
  174.  */
  175. CsFire.HttpUtils.hasReferrer = function(data) {
  176.     var result = false;
  177.     if(    data.referrer_scheme != null ||
  178.             data.referrer_host != null ||
  179.             data.referrer_port != null ||
  180.             data.referrer_uri != null) {
  181.         result = true;        
  182.     }
  183.     return result;
  184. }
  185.  
  186. /*
  187.  * This function decides whether a request is cross-domain or not. The first
  188.  * argument determines the level of strictness, while the second contains
  189.  * all the data about the request. The function returns true or false.
  190.  */
  191. CsFire.HttpUtils.isRequestCrossDomain = function(level, data) {    
  192.     var crossDomain = true;
  193.     if(!this.hasReferrer(data)) {
  194.         //Requests with no origin are considered crossdomain --> changed in version 2.4
  195.         CsFire.Logger.debug("Crossdomain check: no referrer info available ==> crossdomain");
  196.         crossDomain = true;
  197.     }
  198.     else {
  199.         if(data.referrer_scheme == "moz-nullprincipal") {
  200.             //Weird firefox scheme, almost never appears
  201.             CsFire.Logger.debug("Crossdomain check: even firefox doesn't know (moz-nullprincipal) ==> crossdomain");
  202.             crossDomain = true;            
  203.         }
  204.         else {
  205.             if(data.referrer_scheme == null || data.referrer_scheme == "http" || data.referrer_scheme == "https") {
  206.                 //Acceptable scheme, so check cross-domain
  207.                 
  208.                 if(level == this.CROSSDOMAIN_RELAXED) {
  209.                 
  210.                     //Only check domain names
  211.                     if(CsFire.HttpUtils.getDomainName(data.referrer_host) == CsFire.HttpUtils.getDomainName(data.dst_host)) {
  212.                         CsFire.Logger.debug("Crossdomain check (relaxed): same domains ==> not crossdomain");
  213.                         crossDomain = false;        
  214.                     }
  215.                     else {
  216.                         CsFire.Logger.debug("Crossdomain check (relaxed): different domains ==> crossdomain");
  217.                         crossDomain = true;        
  218.                     }
  219.                 }
  220.                 else if(level == this.CROSSDOMAIN_STRICT) {
  221.                     //Check <scheme, host, port>
  222.                     
  223.                     if(data.referrer_host == data.dst_host) {
  224.                         if((data.referrer_scheme == null || data.dst_scheme == null) || data.referrer_scheme == data.dst_scheme) {
  225.                             if((data.referrer_port == null || data.referrer_port == -1 || data.dst_port == null || data.dst_port == -1) || data.referrer_port == data.dst_port) {
  226.                                 CsFire.Logger.debug("Crossdomain check (strict): same <scheme, host, port> ==> not crossdomain");
  227.                                 crossDomain = false;    
  228.                             }
  229.                             else {
  230.                                 CsFire.Logger.debug("Crossdomain check (strict): different ports ==> crossdomain");
  231.                                 crossDomain = true;        
  232.                             }
  233.                         }
  234.                         else {
  235.                             CsFire.Logger.debug("Crossdomain check (strict): different schemes ==> crossdomain");
  236.                             crossDomain = true;        
  237.                         }
  238.                     }
  239.                     else {
  240.                         CsFire.Logger.debug("Crossdomain check (strict): different hosts ==> crossdomain");
  241.                         crossDomain = true;        
  242.                     }
  243.                 }
  244.                 else {
  245.                     var message = "Unknown cross-domnain strictness level: " + level;
  246.                     CsFire.Logger.error(message);
  247.                     throw(message);
  248.                 }
  249.             }
  250.             else {
  251.                 CsFire.Logger.debug("Crossdomain check: probably internal scheme (" + data.referrer_scheme + ") ==> not crossdomain");
  252.                 crossDomain = false;                
  253.             }
  254.         }
  255.     }
  256.     
  257.     return crossDomain;
  258. };
  259.  
  260. /*
  261.  * Converts the numerical value of the cross-domain level to a textual representation.
  262.  */
  263. /*CsFire.HttpUtils.convertCrossDomainLevel = function(level) {
  264.     switch(level) {
  265.         case this.CROSSDOMAIN_RELAXED: return "relaxed";
  266.             break;
  267.         case this.CROSSDOMAIN_STRICT: return "strict";
  268.             break;
  269.     }
  270. }*/
  271.  
  272.  
  273. /*
  274.  * This function converts the numerical content type to a string representation.
  275.  */
  276. /*CsFire.HttpUtils.convertContentType = function(contType) {
  277.     switch(contType) {
  278.         case Components.interfaces.nsIContentPolicy.TYPE_OTHER                    :return "other";
  279.         case Components.interfaces.nsIContentPolicy.TYPE_SCRIPT                    :return "script";
  280.         case Components.interfaces.nsIContentPolicy.TYPE_IMAGE                    :return "image";
  281.         case Components.interfaces.nsIContentPolicy.TYPE_STYLESHEET                :return "stylesheet";
  282.         case Components.interfaces.nsIContentPolicy.TYPE_OBJECT                    :return "object";
  283.         case Components.interfaces.nsIContentPolicy.TYPE_DOCUMENT                :return "document";
  284.         case Components.interfaces.nsIContentPolicy.TYPE_SUBDOCUMENT            :return "subdocument";
  285.         case Components.interfaces.nsIContentPolicy.TYPE_OBJECT                    :return "object";
  286.         case Components.interfaces.nsIContentPolicy.TYPE_REFRESH                :return "refresh";
  287.         case Components.interfaces.nsIContentPolicy.TYPE_XBL                    :return "xbl";
  288.         case Components.interfaces.nsIContentPolicy.TYPE_PING                    :return "ping";
  289.         case Components.interfaces.nsIContentPolicy.TYPE_XMLHTTPREQUEST            :return "xmlhttprequest";
  290.         case Components.interfaces.nsIContentPolicy.TYPE_TYPE_OBJECT_SUBREQUEST    :return "object subrequest";
  291.     }
  292. };*/
  293.